#include "camerathread.h"
#include <QImage>
#include <QDebug>
#include <libswscale/swscale.h>



extern "C" {
#include <libavdevice/avdevice.h>
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libavutil/imgutils.h>
#include <libswscale/swscale.h>
}

cameraThread::cameraThread(AVFormatContext *fmt_ctx) {

    this->fmt_ctx = fmt_ctx;
    // 遍历流，找到视频流索引
    for (int i = 0; i < fmt_ctx->nb_streams; i++) {
        if (fmt_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
            this->video_stream_idx = i;
            break;
        }
    }
}
void cameraThread::run()   {

    AVCodecParameters *codecpar = fmt_ctx->streams[video_stream_idx]->codecpar;
    const AVCodec *codec = avcodec_find_decoder(codecpar->codec_id);
    AVCodecContext *codec_ctx = avcodec_alloc_context3(codec);
    avcodec_parameters_to_context(codec_ctx, codecpar);
    avcodec_open2(codec_ctx, codec, nullptr);

    // 分配帧和包
    AVFrame *frame = av_frame_alloc();
    AVPacket *pkt = av_packet_alloc();

    while (!isInterruptionRequested()) {
        if (av_read_frame(fmt_ctx, pkt) < 0) break;

        if (pkt->stream_index == video_stream_idx) {
            avcodec_send_packet(codec_ctx, pkt);
            if (avcodec_receive_frame(codec_ctx, frame) == 0) {
                // YUV转RGB
                // qDebug()<< frame->format;
                QImage img = convertYUVtoRGB1(frame);
                emit newFrame(img); // 发送信号
            }
        }
        av_packet_unref(pkt);
    }
    // 释放资源...

}


QImage cameraThread::convertYUVtoRGB1(AVFrame* frame) {
    // 检查输入帧是否有效
    if (!frame || !frame->data[0] || frame->width <= 0 || frame->height <= 0) {
        qWarning() << "Invalid frame received!";
        return QImage();
    }

    // 自动检测输入格式并处理格式问题
    // const char* input_format_name = av_get_pix_fmt_name(static_cast<AVPixelFormat>(frame->format));
    // qDebug() << "Input frame format:" << (input_format_name ? input_format_name : "unknown")
    //          << "(" << frame->format << "), size:" << frame->width << "x" << frame->height;

    // 动态更新 SwsContext（当帧参数变化时）
    static SwsContext* sws_ctx = nullptr;
    static int last_width = 0;
    static int last_height = 0;
    static AVPixelFormat last_format = AV_PIX_FMT_NONE;

    // 当帧参数变化时重新创建转换上下文
    if (!sws_ctx ||
        last_width != frame->width ||
        last_height != frame->height ||
        last_format != static_cast<AVPixelFormat>(frame->format))
    {
        if (sws_ctx) {
            sws_freeContext(sws_ctx);
            sws_ctx = nullptr;
        }

        // 自动处理格式兼容性问题
        AVPixelFormat source_format = static_cast<AVPixelFormat>(frame->format);

        // 处理格式不匹配的情况
        if (source_format == AV_PIX_FMT_NONE) {
            qWarning() << "Frame has invalid pixel format, assuming YUV422P";
            source_format = AV_PIX_FMT_YUV422P;
        }

        // 创建 SwsContext
        sws_ctx = sws_getContext(
            frame->width,
            frame->height,
            source_format,          // 使用帧的实际格式
            frame->width,
            frame->height,
            AV_PIX_FMT_RGB32,      // 输出格式为 RGB32 (对应 Qt 的 Format_RGB32)
            SWS_BILINEAR | SWS_ACCURATE_RND | SWS_FULL_CHR_H_INT,
            nullptr,
            nullptr,
            nullptr
            );

        if (!sws_ctx) {
            qCritical() << "Failed to create SwsContext!";
            return QImage();
        }

        last_width = frame->width;
        last_height = frame->height;
        last_format = static_cast<AVPixelFormat>(frame->format);
    }

    // 创建目标 QImage（RGB32）
    QImage img(frame->width, frame->height, QImage::Format_RGB32);
    if (img.isNull()) {
        qCritical() << "Failed to create QImage of size"
                    << frame->width << "x" << frame->height;
        return img;
    }

    // 设置 FFmpeg 输出参数
    uint8_t* rgb_data[AV_NUM_DATA_POINTERS] = { img.bits(), nullptr, nullptr, nullptr };
    int rgb_linesize[AV_NUM_DATA_POINTERS] = { static_cast<int>(img.bytesPerLine()), 0, 0, 0 };

    // 执行颜色空间转换
    int result = sws_scale(
        sws_ctx,
        frame->data,     // 输入数据
        frame->linesize, // 输入行大小
        0,               // 起始行
        frame->height,   // 总行数
        rgb_data,        // 输出数据（RGB32）
        rgb_linesize     // 输出行大小
        );

    if (result < 0) {
        qWarning() << "sws_scale failed with error:" << result;
        return QImage();
    }

    return img;
}
